/*******************************************************************************
 * Copyright (c) 2001, 2002 Boris Pruessmann and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v0.5
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors:
 *    Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.action;

import java.lang.reflect.InvocationTargetException;

import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.PerforceSynchronizer;
import net.sourceforge.perforce.core.internal.P4TeamProvider;
import net.sourceforge.perforce.core.resources.RemoteFolder;
import net.sourceforge.perforce.ui.PerforceUIPlugin;
import net.sourceforge.perforce.ui.internal.Policy;
import org.eclipse.core.internal.resources.ProjectDescription;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.ui.actions.WorkspaceModifyOperation;

/**
  * @version  $Revision: 249 $
  * @author   <a href="mailto:bpruessmann@users.sourceforge.net">Boris Pruessmann</a>
  */
public class CheckoutAction extends PerforceAction
{
	// ------------------------------------------------------------------------------ Public Methods
	
	/** @see IActionDelegate#run(IAction) */
	public void run(IAction action)
	{
		run(new WorkspaceModifyOperation()
		{
			public void execute(IProgressMonitor monitor)
				throws InvocationTargetException, InterruptedException
			{
				try 
				{
					PerforceSynchronizer.getInstance().beginOperation(monitor);
					
					IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();					
					RemoteFolder[] folders = getSelectedRemoteFolders();
					
					monitor.beginTask("", folders.length * 1000);
					for (int i = 0; i < folders.length; i++)
					{
						final String projectName = getProjectName(folders[i].getName());
						if (projectName == null)
						{
							return;
						}
						
						IProject project = root.getProject(projectName);
						if (project.exists())
						{
							getShell().getDisplay().syncExec(new Runnable() 
							{
								public void run() 
								{
									ErrorDialog.openError(
										getShell(),
										"Error",
										"The workspace already contains the project " + projectName,
										new Status(
											Status.ERROR, 
											PerforceUIPlugin.ID,
											Status.ERROR, 
											"",
											null));
								}
							});
						}
						else
						{	
							monitor.setTaskName(
								"Checking out '" + projectName + "' from Perforce...");
							
							folders[i].sync("#head", Policy.subMonitorFor(monitor, 300));
							
							IProjectDescription projectDescription = new ProjectDescription();
							projectDescription.setName(project.getName());
							projectDescription.setLocation(folders[i].getLocation());
							
							project.create(projectDescription, Policy.subMonitorFor(monitor, 100));
							
							if (!project.isOpen())
							{
								project.open(Policy.subMonitorFor(monitor, 100));
							}
							else
							{
								project.refreshLocal(
									IResource.DEPTH_INFINITE, Policy.subMonitorFor(monitor, 100));
							}

							PerforceCorePlugin.getServerManager().setSharing(
								project, 
								folders[i].getServer(), 
								Policy.subMonitorFor(monitor, 100));
								
							P4TeamProvider provider = 
								(P4TeamProvider) RepositoryProvider.getProvider(project);
							provider.refreshState(
								new IResource[] { project }, 
								IResource.DEPTH_INFINITE, 
								Policy.subMonitorFor(monitor, 400));
						}						
					}
				} 
				catch (CoreException e) 
				{
					throw new InvocationTargetException(e);
				} 
				catch (TeamException e) 
				{
					throw new InvocationTargetException(e);						
				}
				finally
				{
					try {
						PerforceSynchronizer.getInstance().endOperation(monitor);
					} 
					catch (PerforceException e) 
					{
						PerforceUIPlugin.log(e.getStatus());
					}
					monitor.done();
				}
			}
		}, PROGRESS_DIALOG, false);
	}
	
	// --------------------------------------------------------------------------- Protected Methods
	
	/** @see TeamAction#isEnabled() */
	protected boolean isEnabled() 
		throws PerforceException
	{
		RemoteFolder[] folders = getSelectedRemoteFolders();						
		return folders.length > 0;
	}
	
	/** Returns the name under which the given project should be created. 
	  * 
	  * @param projectName the name of the project.
	  * @return the name under which the project will be created or null to abort.
	  */
	protected String getProjectName(String projectName)
	{
		return projectName;
	}
}
